<template>
  <div ref="container" class="parking-scene">
    <div v-if="loading" class="loading">
      <div class="progress-bar">
        <div class="progress" :style="{ width: `${loadProgress}%` }"></div>
      </div>
      <div class="progress-text">{{ loadProgress }}%</div>
    </div>
    <div v-if="!loading" class="controls">
      <button @click="toggleGrid">网格: {{ showGrid ? 'ON' : 'OFF' }}</button>
      <button @click="addRandomCar">添加随机车辆</button>
      <button @click="removeRandomCar">移除随机车辆</button>
      <div class="stats">
        车位总数: {{ totalSlots }} | 已占用: {{ occupiedSlots }} | 剩余: {{ totalSlots - occupiedSlots }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'

// DOM引用和状态
const container = ref(null)
const loading = ref(true)
const loadProgress = ref(0)
const showGrid = ref(true)
const selectedSlot = ref(null)

// 停车场数据
const parkingSlots = ref(Array(20).fill().map((_, i) => ({
  id: i,
  occupied: false,
  vehicle: null,
  position: {
    x: (i % 5) * 4 - 8,
    y: 0,
    z: Math.floor(i / 5) * 7 - 14
  }
})))

// 计算属性
const totalSlots = computed(() => parkingSlots.value.length)
const occupiedSlots = computed(() => parkingSlots.value.filter(s => s.occupied).length)

// Three.js对象
let scene, camera, renderer, controls, gridHelper, raycaster
const carModels = ref([])
const carColors = [
  '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF',
  '#FFA500', '#A52A2A', '#008000', '#800080', '#00FFFF'
]

// 更新车位颜色
function updateSlotColor(slotId, occupied) {
  scene.children.forEach(child => {
    if (child.userData.type === 'slot' && child.userData.id === slotId) {
      child.material.color.setHex(occupied ? 0xff4444 : 0x44ff44)
    }
  })
}

// 处理点击事件
function onPointerClick(event) {
  if (!raycaster) return

  // 计算鼠标位置
  const mouse = new THREE.Vector2()
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1

  // 设置射线
  raycaster.setFromCamera(mouse, camera)

  // 检测相交对象
  const intersects = raycaster.intersectObjects(scene.children, true)

  if (intersects.length > 0) {
    const clickedObject = intersects[0].object
    if (clickedObject.userData.type === 'slot') {
      const slotId = clickedObject.userData.id
      const slot = parkingSlots.value.find(s => s.id === slotId)

      if (slot.occupied) {
        removeVehicleFromSlot(slotId)
      } else {
        addVehicleToSlot(slotId)
      }
    }
  }
}

// 切换网格显示
function toggleGrid() {
  showGrid.value = !showGrid.value
  if (gridHelper) {
    gridHelper.visible = showGrid.value
  }
}

// 添加随机车辆
function addRandomCar() {
  addRandomVehicles(1)
}

// 移除随机车辆
function removeRandomCar() {
  const occupiedSlots = parkingSlots.value.filter(s => s.occupied)
  if (occupiedSlots.length === 0) return

  const randomIndex = Math.floor(Math.random() * occupiedSlots.length)
  removeVehicleFromSlot(occupiedSlots[randomIndex].id)
}

// 窗口大小调整
function onWindowResize() {
  if (!camera || !renderer) return
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
}

// 动画循环
function animate() {
  requestAnimationFrame(animate)
  if (controls) controls.update()
  if (renderer && scene && camera) renderer.render(scene, camera)
}

// 初始化场景
async function initScene() {
  // 1. 创建场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x333333)

  // 添加环境光遮蔽效果
  scene.fog = new THREE.FogExp2(0x333333, 0.01)

  // 2. 创建相机
  camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  )
  camera.position.set(20, 25, 20)
  camera.lookAt(0, 0, 0)

  // 3. 创建渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFSoftShadowMap
  container.value.appendChild(renderer.domElement)

  // 4. 添加控制器
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.05
  controls.minDistance = 10
  controls.maxDistance = 50

  // 5. 添加更真实的光源
  // 环境光
  const ambientLight = new THREE.AmbientLight(0x404040, 0.7)
  scene.add(ambientLight)

  // 主方向光（太阳）
  const directionalLight = new THREE.DirectionalLight(0xffffff, 1)
  directionalLight.position.set(10, 20, 10)
  directionalLight.castShadow = true
  directionalLight.shadow.mapSize.width = 2048
  directionalLight.shadow.mapSize.height = 2048
  directionalLight.shadow.camera.near = 0.5
  directionalLight.shadow.camera.far = 50
  directionalLight.shadow.camera.left = -20
  directionalLight.shadow.camera.right = 20
  directionalLight.shadow.camera.top = 20
  directionalLight.shadow.camera.bottom = -20
  scene.add(directionalLight)

  // 辅助光
  const hemisphereLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.5)
  scene.add(hemisphereLight)

  // 6. 添加更真实的地面
  const groundGeometry = new THREE.PlaneGeometry(50, 50)
  const groundTexture = new THREE.TextureLoader().load('https://threejs.org/examples/textures/terrain/grasslight-big.jpg')
  groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping
  groundTexture.repeat.set(10, 10)
  const groundMaterial = new THREE.MeshStandardMaterial({
    map: groundTexture,
    roughness: 0.8,
    metalness: 0.2
  })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  ground.receiveShadow = true
  scene.add(ground)

  // 添加地面标记线
  const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff })
  for (let i = -20; i <= 20; i += 4) {
    const lineGeometry = new THREE.BufferGeometry().setFromPoints([
      new THREE.Vector3(-25, 0.01, i),
      new THREE.Vector3(25, 0.01, i)
    ])
    const line = new THREE.Line(lineGeometry, lineMaterial)
    ground.add(line)
  }

  // 7. 添加网格辅助
  gridHelper = new THREE.GridHelper(50, 50, 0x888888, 0x444444)
  scene.add(gridHelper)

  // 8. 初始化射线检测
  raycaster = new THREE.Raycaster()

  // 9. 加载汽车模型
  await loadCarModels()

  // 10. 创建停车位
  createParkingSlots()

  // 11. 添加一些初始车辆
  addRandomVehicles(5)

  loading.value = false
}

// 加载汽车模型
async function loadCarModels() {
  const loader = new GLTFLoader()
  const dracoLoader = new DRACOLoader()
  dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.5/')
  loader.setDRACOLoader(dracoLoader)

  // 使用可用的汽车模型URL
const modelUrls = [
  'https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf',
  'https://threejs.org/examples/models/gltf/LittlestTokyo.glb',
  'https://threejs.org/examples/models/gltf/duck/glTF/Duck.gltf'
]

  for (const url of modelUrls) {
    try {
      const gltf = await new Promise((resolve, reject) => {
        loader.load(url, resolve, undefined, reject)
      })
      carModels.value.push(gltf.scene)
    } catch (error) {
      console.error('Failed to load car model:', error)
      // 如果模型加载失败，创建一个简单的汽车模型作为后备
      const carGroup = new THREE.Group()

      // 车身
      const bodyGeometry = new THREE.BoxGeometry(2.5, 1, 4)
      const bodyMaterial = new THREE.MeshStandardMaterial({
        color: 0xff0000,
        metalness: 0.7,
        roughness: 0.3
      })
      const body = new THREE.Mesh(bodyGeometry, bodyMaterial)
      body.position.y = 0.5
      carGroup.add(body)

      // 车顶
      const roofGeometry = new THREE.BoxGeometry(2.2, 0.3, 2.5)
      const roof = new THREE.Mesh(roofGeometry, bodyMaterial)
      roof.position.y = 1.15
      roof.position.z = -0.3
      carGroup.add(roof)

      // 车窗
      const windowGeometry = new THREE.BoxGeometry(2.2, 0.5, 2.4)
      const windowMaterial = new THREE.MeshStandardMaterial({
        color: 0x333333,
        transparent: true,
        opacity: 0.7,
        metalness: 0.9,
        roughness: 0.1
      })
      const window = new THREE.Mesh(windowGeometry, windowMaterial)
      window.position.y = 1.1
      window.position.z = -0.3
      carGroup.add(window)

      // 车轮
      const wheelGeometry = new THREE.CylinderGeometry(0.3, 0.3, 0.2, 32)
      const wheelMaterial = new THREE.MeshStandardMaterial({ color: 0x222222 })

      const wheelPositions = [
        { x: 1.1, y: 0.2, z: 1.3, ry: Math.PI/2 },
        { x: -1.1, y: 0.2, z: 1.3, ry: Math.PI/2 },
        { x: 1.1, y: 0.2, z: -1.3, ry: Math.PI/2 },
        { x: -1.1, y: 0.2, z: -1.3, ry: Math.PI/2 }
      ]

      wheelPositions.forEach(pos => {
        const wheel = new THREE.Mesh(wheelGeometry, wheelMaterial)
        wheel.position.set(pos.x, pos.y, pos.z)
        wheel.rotation.x = pos.ry
        carGroup.add(wheel)
      })

      carModels.value.push(carGroup)
    }
  }
}

// 创建停车位
function createParkingSlots() {
  parkingSlots.value.forEach(slot => {
    const slotGeometry = new THREE.BoxGeometry(3, 0.1, 5)
    const slotMaterial = new THREE.MeshStandardMaterial({
      color: slot.occupied ? 0xff4444 : 0x44ff44,
      transparent: true,
      opacity: 0.8
    })

    const slotMesh = new THREE.Mesh(slotGeometry, slotMaterial)
    slotMesh.position.set(slot.position.x, slot.position.y, slot.position.z)
    slotMesh.userData = { type: 'slot', id: slot.id }
    slotMesh.castShadow = true
    slotMesh.receiveShadow = true
    scene.add(slotMesh)

    // 添加停车位标记线
    const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 2 })
    const lineGeometry = new THREE.BufferGeometry().setFromPoints([
      new THREE.Vector3(slot.position.x - 1.5, 0.02, slot.position.z - 2.5),
      new THREE.Vector3(slot.position.x + 1.5, 0.02, slot.position.z - 2.5),
      new THREE.Vector3(slot.position.x + 1.5, 0.02, slot.position.z + 2.5),
      new THREE.Vector3(slot.position.x - 1.5, 0.02, slot.position.z + 2.5),
      new THREE.Vector3(slot.position.x - 1.5, 0.02, slot.position.z - 2.5)
    ])
    const line = new THREE.Line(lineGeometry, lineMaterial)
    scene.add(line)
  })
}

// 添加随机车辆
function addRandomVehicles(count) {
  const availableSlots = parkingSlots.value.filter(s => !s.occupied)
  const slotsToFill = Math.min(count, availableSlots.length)

  for (let i = 0; i < slotsToFill; i++) {
    const randomIndex = Math.floor(Math.random() * availableSlots.length)
    const slot = availableSlots[randomIndex]
    addVehicleToSlot(slot.id)
    availableSlots.splice(randomIndex, 1)
  }
}

// 添加车辆到指定车位
function addVehicleToSlot(slotId) {
  const slotIndex = parkingSlots.value.findIndex(s => s.id === slotId)
  if (slotIndex === -1 || parkingSlots.value[slotIndex].occupied) return

  // 随机选择一个汽车模型
  if (carModels.value.length === 0) return

  const modelIndex = Math.floor(Math.random() * carModels.value.length)
  const carModel = carModels.value[modelIndex].clone()

  // 设置汽车颜色
  const color = new THREE.Color(carColors[Math.floor(Math.random() * carColors.length)])

  // 遍历模型并设置颜色和阴影
  carModel.traverse(child => {
    if (child.isMesh) {
      if (child.material.name !== 'window') { // 不要改变车窗颜色
        child.material.color = color
      }
      child.castShadow = true
      child.receiveShadow = true
    }
  })

  // 调整汽车位置和大小
  carModel.position.set(
    parkingSlots.value[slotIndex].position.x,
    0,
    parkingSlots.value[slotIndex].position.z
  )

  // 随机旋转方向 (0° 或 180°)
  carModel.rotation.y = Math.random() > 0.5 ? 0 : Math.PI

  // 统一缩放模型
  carModel.scale.set(0.8, 0.8, 0.8)

  // 根据模型类型调整位置
  if (modelIndex < 3) { // 如果是GLTF模型
    carModel.position.y = 0.5
  }

  carModel.userData = { type: 'vehicle', slotId }
  scene.add(carModel)

  // 更新车位状态
  parkingSlots.value[slotIndex].occupied = true
  parkingSlots.value[slotIndex].vehicle = carModel

  // 更新车位颜色
  updateSlotColor(slotId, true)
}

// 从车位移除车辆
function removeVehicleFromSlot(slotId) {
  const slotIndex = parkingSlots.value.findIndex(s => s.id === slotId)
  if (slotIndex === -1 || !parkingSlots.value[slotIndex].occupied) return

  // 查找并移除车辆
  const vehicle = parkingSlots.value[slotIndex].vehicle
  scene.remove(vehicle)

  // 更新车位状态
  parkingSlots.value[slotIndex].occupied = false
  parkingSlots.value[slotIndex].vehicle = null

  // 更新车位颜色
  updateSlotColor(slotId, false)
}

onMounted(() => {
  initScene()
  animate()
  window.addEventListener('resize', onWindowResize)
  if (renderer) {
    renderer.domElement.addEventListener('click', onPointerClick)
  }

  // 模拟加载进度
  const interval = setInterval(() => {
    loadProgress.value += 5
    if (loadProgress.value >= 100) {
      clearInterval(interval)
    }
  }, 100)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', onWindowResize)
  if (renderer) {
    renderer.domElement.removeEventListener('click', onPointerClick)
  }
  if (container.value && renderer) {
    container.value.removeChild(renderer.domElement)
  }
})
</script>

<style scoped>
.parking-scene {
  width: 100%;
  height: 100vh;
  position: relative;
}

.loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: white;
}

.progress-bar {
  width: 200px;
  height: 20px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 10px;
}

.progress {
  height: 100%;
  background: linear-gradient(90deg, #4CAF50, #8BC34A);
  transition: width 0.3s;
}

.progress-text {
  font-size: 18px;
}

.controls {
  position: absolute;
  bottom: 20px;
  left: 20px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

button {
  padding: 8px 16px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border: 1px solid #4CAF50;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
}

button:hover {
  background: rgba(76, 175, 80, 0.7);
}

.stats {
  padding: 8px 16px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border-radius: 4px;
}
</style>
